package org.bbs.demo.advice;

import lombok.extern.slf4j.Slf4j;
import org.bbs.demo.common.BBSConstants;
import org.bbs.demo.common.Result;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j  //该注解可以实现方便的日志输出
@RestControllerAdvice   //说明本类可以拦截Api异常
public class BBSApiAdvice {

    /*
        业务错误
     */
    @ExceptionHandler(BusinessException.class)  //具体拦截异常的方法
    public Result handleBusinessException(BusinessException e){

        return Result.err(BBSConstants.CODE_ERR_BUSINESS, e.getMessage());
    }

    /*
        Token错误
     */
    @ExceptionHandler(TokenException.class)  //具体拦截异常的方法
    public Result handleTokenException(TokenException e){

        log.error("Token错误!", e);
        return Result.err(BBSConstants.CODE_ERR_BUSINESS, e.getMessage());
    }

    /*
        系统错误
     */
    @ExceptionHandler(SysException.class)       //具体拦截异常的方法
    public Result handleSyxException(SysException e){

        log.error("系统错误!", e);
        return Result.err(BBSConstants.CODE_ERR_SYS, e.getMessage());
    }

    /*
        前端数据验证错误
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException e){

        log.error("系统错误!", e);

        List<FieldError> fieldErrorList = e.getFieldErrors();

        String str =
            fieldErrorList.stream()
                .map(fieldError -> "["+fieldError.getField()+"]"+fieldError.getDefaultMessage())
                .collect(Collectors.joining(";"));

        return Result.err(BBSConstants.CODE_ERR_SYS, str);

    }

    /*
        前端数据验证错误
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public Result handleConstraintViolationException(ConstraintViolationException e){

        log.error("系统错误!", e);

        String str =
            e.getConstraintViolations().stream()
                .map(violation -> "["+violation.getPropertyPath()+"]"+violation.getMessage())
                .collect(Collectors.joining(";"));

        return Result.err(BBSConstants.CODE_ERR_SYS, str);
    }

    /*
        前端数据验证错误
     */
    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    public Result handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e){

        log.error("系统错误!", e);

        String str = "参数["+e.getName()+"]值"+e.getValue()+",不匹配类型"+e.getRequiredType().getName();
        return Result.err(BBSConstants.CODE_ERR_SYS, str);

    }

    /*
        其他系统错误
     */
    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e){

        log.error("其他系统错误!", e);
        return Result.err(BBSConstants.CODE_ERR_SYS, "其他系统错误!");
    }


}
